<!--
 * 轮播
 * @作者: 陈老师儿~
 * @手机: 18560000860
 -->
<template>
    <view class="pure-swiper" :class="classes" :style="styles" @tap="handleClick">
        <!-- Swiper -->
        <swiper
            class="pure-swiper-swiper"
            :active-class="activeClass"
            :changing-class="changingClass"
            :autoplay="autoplay"
            :current="current"
            :interval="interval"
            :duration="duration"
            :circular="circular"
            :vertical="vertical"
            :previous-margin="previousMargin"
            :next-margin="nextMargin"
            :acceleration="acceleration"
            :disable-programmatic-animation="disableProgrammaticAnimation"
            :display-multiple-items="displayMultipleItems"
            :skip-hidden-item-layout="skipHiddenItemLayout"
            :disable-touch="disableTouch"
            :touchable="touchable"
            :easing-function="easingFunction"
            @change="handleChange"
            @transition="handleTransition"
            @animationfinish="handleAnimationFinish"
        >
            <slot v-if="$slots.default"></slot>
            <template v-else>
                <swiper-item class="pure-swiper-item" v-for="(_item, _index) in list" :key="_index" :class="itemClasses(_index, _item)" @tap="handleClick(_index, _item)">
                    <view class="pure-swiper-item-wrapper">
                        <pure-image :src="mediaSrc(_item)" :placeholder="placeholderSrc(_item)" :mode="mediaMode" v-bind="imageOpts"></pure-image>
                    </view>
                </swiper-item>
            </template>
        </swiper>

        <!-- Indicator -->
        <slot name="indicator" v-if="$slots.indicator"></slot>
        <pure-indicator
            v-else-if="indicator"
            :mode="indicatorMode"
            :count="list?.length"
            :current="current"
            :separator="separator"
            :hoverClass="indicatorHoverClass"
            :list="list"
            @onClick="handleIndicatorItemClick"
        ></pure-indicator>

        <!-- 左右箭头 -->
        <slot name="arrow" v-if="$slots.arrow"></slot>
        <pure-prev-next
            :prevIcon="prevIcon"
            :nextIcon="nextIcon"
            :prevDisabled="isDisabledPrev"
            :nextDisabled="isDisabledNext"
            :disabledClass="arrowDisabledClass"
            :hoverClass="arrowHoverClass"
            :count="list?.length"
            :loop="circular"
            @prev="handlePrev"
            @next="handleNext"
            v-else-if="arrow"
        ></pure-prev-next>
    </view>
</template>

<script>
    import props from "./props.js";
    export default {
        options: {
            // 将自定义节点设置成虚拟的
            // 头条、飞书：因为合并后丢失事件和 'provide/inject'
            // 京东：因为合并后不能合并外层 'class'
            // 百度：因为合并后会在控制台疯狂报警告
            // #ifndef MP-TOUTIAO || MP-LARK || MP-JD || MP-BAIDU
            virtualHost: true,
            // #endif

            // 组件样式隔离
            styleIsolation: "apply-shared",

            // 允许使用多个插槽
            multipleSlots: true,
        },
        props: props,
        emits: ["change", "transition", "animationfinish", "itemClick", "prev", "next", "indicatorItemClick"],
        computed: {
            // classes
            classes() {
                const classes = [];
                return classes;
            },

            // styles
            styles() {
                const styles = [];

                // 宽
                if (this.width) styles.push(`--pure-swiper-width: ${this.width};`);

                // 高
                if (this.height) styles.push(`--pure-swiper-height: ${this.height};`);

                return styles;
            },

            // 是否禁用左箭头
            isDisabledPrev() {
                return this.current === 0 && !this.circular;
            },

            // 是否禁用右箭头
            isDisabledNext() {
                return this.current === this.list?.length - 1 && !this.circular;
            },
        },
        methods: {
            // 切换事件
            handleChange(e) {
                this.$emit("change", e);
            },

            // swiper-item 的位置发生改变时会触发 transition 事件
            handleTransition(e) {
                this.$emit("transition", e);
            },

            // 动画结束时会触发 animationfinish 事件
            handleAnimationFinish(e) {
                this.$emit("animationfinish", e);
            },

            // item 点击事件
            handleClick(index, item) {
                if (item?.disabled) return;
                this.$emit("itemClick", index, item);
            },

            // item classes
            itemClasses(index, item) {
                const classes = [];

                // 选中
                if (index === this.current) classes.push(item?.activedClass || this.activedClass);
                // 未选中
                else classes.push(item?.inactivedClass || this.inactivedClass);

                // 自定义类名
                if (item?.itemClass) classes.push(item?.itemClass);
                if (typeof this.formatItemClass === "function") classes.push(this.formatItemClass(index, item));

                // 禁用
                if (item?.disabled) classes.push(item?.disabledClass || this.disabledClass);

                return classes;
            },

            // 资源地址
            mediaSrc(item) {
                return item?.[item?.mediaKey] || item?.[this.mediaKey] || "";
            },

            // 占位资源地址
            placeholderSrc(item) {
                return item?.[item?.placeholderKey] || item?.[this.placeholderKey] || "";
            },

            // 指示器点击事件
            handleIndicatorItemClick(index) {
                this.$emit("indicatorItemClick", index);
            },

            // 上一个
            handlePrev() {
                let index = this.current - 1;
                if (index < 0) index = this.list?.length - 1;
                this.$emit("prev", index);
            },

            // 下一个
            handleNext() {
                let index = this.current + 1;
                if (index > this.list?.length - 1) index = 0;
                this.$emit("next", index);
            },
        },
    };
</script>

<style scoped>
    @import "./style.css";
</style>
